package edu.ccut.saturn.authority.impl.department;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import edu.ccut.saturn.component.DefaultComponent;
import edu.ccut.saturn.component.IParameterContext;



public class GetExtJSTreeList extends DefaultComponent {
	
	@SuppressWarnings("unchecked")
	@Override
	public void execute(IParameterContext parameterContext) throws Exception {
		TreeInfo treeInfo = new TreeInfo();
		List<Map<String, String>> list = (List<Map<String, String>>)parameterContext.getParameterValue(0);
		ListNullToString(list);
		treeInfo.id = parameterContext.getParameterValue(1).toString();
		treeInfo.text = parameterContext.getParameterValue(2).toString();
		treeInfo.parentId = parameterContext.getParameterValue(3).toString();
		treeInfo.rootIdValue = parameterContext.getParameterValue(4).toString();
		parameterContext.setParameter(5, generateExtjsTreeList(list, treeInfo));
	}

	private List<Map<String, Object>> generateExtjsTreeList(
			List<Map<String, String>> tree, TreeInfo treeInfo) {
		
		List<Map<String, String>> rootNodes = getChildrenTreeNodeById(treeInfo.rootIdValue, tree, treeInfo);
		
		List<Map<String, Object>> jsonTree = new ArrayList<Map<String, Object>>();
		LinkedList<Map<String, Object>> queue = new LinkedList<Map<String, Object>>();
		if(rootNodes != null){
			for (Map<String, String> root : rootNodes) {
				Map<String, Object> extjsRoot = this.createExtjsTreeNode(root, treeInfo);
				queue.add(extjsRoot);
				jsonTree.add(extjsRoot);
			}
		}

		while (!queue.isEmpty()) {
			Map<String, Object> node = queue.removeLast();

			List<Map<String, String>> children = this.getChildrenTreeNodeById(
					(String)node.get(treeInfo.id), tree, treeInfo);
			if(children != null){
				for (Map<String, String> child : children) {
					Map<String, Object> extjsChild = this.createExtjsTreeNode(child,treeInfo);
					
					this.addExtjsTreeChildNode(node, extjsChild);
					queue.add(extjsChild);
				}
			}
		}
		
		return jsonTree;
	}

	private List<Map<String, String>> getChildrenTreeNodeById(String id,
			List<Map<String, String>> allNodes, TreeInfo treeInfo) {
		List<Map<String, String>> nodes = new ArrayList<Map<String, String>>();
		if(allNodes!=null){
			for (Map<String, String> node : allNodes) {
				if (id.equals(node.get(treeInfo.parentId))) {
					nodes.add(node);
				}
			}
		}

		return nodes;
	}

	private Map<String, Object> createExtjsTreeNode(Map<String, String> oldNode
			,TreeInfo treeInfo) {

		Map<String, Object> node = new HashMap<String, Object>();

		node.put("id", oldNode.get(treeInfo.id));
		node.put("text", oldNode.get(treeInfo.text));
		node.put("parentId", oldNode.get(treeInfo.parentId));
		
		List<String> keyList = new ArrayList<String>();
		keyList.add(treeInfo.id);
		keyList.add(treeInfo.text);
		keyList.add(treeInfo.parentId);
		if(oldNode!=null){
			for(String key: oldNode.keySet()){
				if(!(keyList.contains(key))){
					node.put(key, oldNode.get(key));
				}
			}
		}
		
		node.put("allowDrag", false);
		node.put("leaf", true);

		return node;
	}

	@SuppressWarnings("unchecked")
	private void addExtjsTreeChildNode(Map<String, Object> node,
			Map<String, Object> child) {
		
		List<Map<String, Object>> children = (List<Map<String, Object>>) node.get("children");
		if (children == null) {
			children = new ArrayList<Map<String,Object>>();
			node.put("children", children);
			node.put("leaf", false);
		}
		
		children.add(child);
	}
	
	@SuppressWarnings("unused")
	private void ListNullToString(List<Map<String, String>> list){
		if(list !=null){
			for(Map<String, String> map: list){
				if(map != null){
					for(String key: map.keySet()){
						if(map.get(key) == null){
							map.put(key, "");
						}
					}
				}
			}
		}
	}
}

class TreeInfo {
	public String id;
	public String text;
	public String parentId;
	public String rootIdValue;
}